package chat.common;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.io.*;
import java.util.*;

/**
 * Message used by application
 * @author Berthier Sebastien, Marigny Julien
 */
public class Message {

    public static final int CONNECTION = 0;
    public static final int DECONNECTION = 1;
    public static final int ERROR_CONNECTION = 2;
    public static final int ACK_CONNECTION = 3;

    public static final int TEXT = 10;
    public static final int ACK_TEXT = 11; // pas utilise finalement
    public static final int LIST = 12;
    public static final int FILE = 13;

    public static final int FILEOK = 8;
    public static final int FILEDATA = 9;
    public static final int FILE_NON = 7;

    public static final int CONNECTION_CLIENT = 20;
    public static final int DECONNECTION_CLIENT = 21;
    public static final int NOTIFY_ADD_CHANNEL = 22; // envoie pour les client
    public static final int NOTIFY_RM_CHANNEL = 23;
    public static final int ADD_CHANNEL = 24; // un client envois pour le server
    public static final int RM_CHANNEL = 25;
    public static final int NEW_CLIENT_CHANNEL = 26;
    public static final int RM_CLIENT_CHANNEL = 27;
    /**
     * identification du type du message
     */
    private int type;
    private String src;
    private String dest;
    /**
     * le contenu du message, facultatif (pas utilise dans CONNECTION,
     * DECONNECTION, ERROR_CONNECTION, ACK_CONNECTION.
     */
    private byte[] tabByte = null;

    /**
     *
     * @return le contenu du message sous forme de string.
     */
    public String getMessageStr() {
        String message = new String(tabByte);
        return message;
    }

    /**
     *
     * @param message le conetnu du message sous fiorme de string.
     */
    public void setMessageStr(String message) {
        this.tabByte = message.getBytes();
    }

    /**
     *
     * @return le contenu du message sous forme de tableau de byte.
     */
    public byte[] getMessage() {
        return tabByte;
    }

    /**
     *
     * @return le contenu du message sous forme de tableau de byte.
     */
    public char[] getMessageChar() {
        char[] tabChar = new char[tabByte.length];
        for (int i = 0; i < tabByte.length; i++) {
            tabChar[i] = (char) tabByte[i];
        }
        return tabChar;
    }

    /**
     *
     * @param message le conetnu du message sous forme de tableau de byte.
     */
    public void setMessage(byte[] message) {
        this.tabByte = message;
    }

    /**
     *
     * @return le type du message, un Int qui l'identifie
     */
    public int getType() {
        return type;
    }

    /**
     *
     * @param type le type du message, un Int qui l'identifie
     */
    public void setType(int type) {
        this.type = type;
    }

    /**
     *
     * @return La destination
     */
    public String getDest() {
        return dest;
    }

    /**
     *
     * @param dest La destination
     */
    public void setDest(String dest) {
        this.dest = dest;
    }

    /**
     *
     * @return La source
     */
    public String getSrc() {
        return src;
    }

    /**
     *
     * @param src La source
     */
    public void setSrc(String src) {
        this.src = src;
    }

    /**
     * Constructeur vide
     */
    public Message() {
    }

    /**
     *
     * @param type L'indentifiant du type du message (CONNECTION, DECONNECION...à)
     * @param src La sources
     * @param dest La destination
     */
    public Message(int type, String src, String dest) {
        this.type = type;
        this.src = src;
        this.dest = dest;
    }

    /**
     *
     * @param type L'indentifiant du type du message (CONNECTION, DECONNECION...à)
     * @param src La sources
     * @param dest La destination
     * @param message Le contenu sous forme de string
     */
    public Message(int type, String src, String dest, String message) {
        this.type = type;
        this.src = src;
        this.dest = dest;
        this.tabByte = message.getBytes();
    }

     /**
     *
     * @param type L'indentifiant du type du message (CONNECTION, DECONNECION...à)
     * @param tabBytes Le conetnu sous forme de tableau de byte
     */
    public Message(int type, char[] tabChar) {
        this.type = type;
        this.tabByte = new byte[tabChar.length];
        for (int i = 0; i < tabChar.length; i++) {
            this.tabByte[i] = (byte) tabChar[i];
        }

    }

    /**
     *
     * @param type L'indentifiant du type du message (CONNECTION, DECONNECION...à)
     * @param tabBytes Le conetnu sous forme de tableau de byte
     */
    public Message(int type, byte[] tabBytes) {
        this.type = type;
        this.tabByte = new byte[tabByte.length];
        this.tabByte = tabBytes;

    }

    /**
     *
     * @param type L'indentifiant du type du message (CONNECTION, DECONNECION...à)
     * @param src La sources
     * @param dest La destination
     * @param tabBytes Le conetnu sous forme de tableau de byte
     */
    public Message(int type, String src, String dest, byte[] tabBytes) {
        this.type = type;
        this.src = src;
        this.dest = dest;
        this.tabByte = new byte[tabByte.length];
        this.tabByte = tabBytes;

    }

    /**
     *
     * @param type L'indentifiant du type du message (CONNECTION, DECONNECION...à)
     * @param src La sources
     * @param dest La destination
     * @param tabChar Le contenu sous forme de tableau de character
     */
    public Message(int type, String src, String dest, char[] tabChar) {
        this.type = type;
        this.src = src;
        this.dest = dest;
        // conversion du tableau de character en tableau de byte.
        this.tabByte = new byte[tabChar.length];
        for (int i = 0; i < tabChar.length; i++) {
            this.tabByte[i] = (byte) tabChar[i];
        }
    }

    /**
     * si c'est pas un simple message (Connection, deconnection ... ack)
     * alors on ecrit la partie "info" du message
     * @param sortie Le flux de sortie de la connection où envoyer le message
     */
    public void sendMessage(DataOutputStream sortie) throws Exception {
        try {
            sortie.writeInt(type);
            if (type != FILEDATA) {
            sortie.writeUTF(src);
            sortie.writeUTF(dest);
            }
            // Dans certains cas, on allege le message qui n'a pas besoin de contenu
            if (type != CONNECTION && type != DECONNECTION
                    && type != ERROR_CONNECTION && type != ACK_CONNECTION) {
                sortie.writeInt(tabByte.length);
                sortie.write(this.tabByte, 0, this.tabByte.length);
            }
        } catch (Exception e) {
           // System.out.println("error write message : " + e.toString());
            throw new Exception();
        }
    }

    /**
     * si c'est pas un simple message (Connection, deconnection ... ack)
     * alors on lis la partie "info" du message
     * @param entree Le flux d'entre de la connection où recevoir le message
     */
    public void readMessage(DataInputStream entree) throws Exception {
        try {
            type = entree.readInt();
            if (type != FILEDATA) {
            src = entree.readUTF();
            dest = entree.readUTF();
            }
            if (type != CONNECTION && type != DECONNECTION
                    && type != ERROR_CONNECTION && type != ACK_CONNECTION) {
                int length = entree.readInt();
                this.tabByte = new byte[length];
                entree.read(this.tabByte, 0, length);
            }
        } catch (Exception e) {
         //   System.out.println("error read message : " + e.toString());
            throw new Exception();
        }
    }

    /**
     * sert pour la commutation de message niveau server
     * La source devient la destination.
     * La destination devient le source.
     */
    public void revertSrcDest() {
        String destination = src;
        src = dest;
        dest = destination;

    }
}

